from fastapi import APIRouter, Body, Path, Query, Depends
from backend.db.neo4j_driver import neo4j_driver
from backend.utils.logger import logger
from backend.utils.response_filter import filter_sensitive_fields
from backend.schemas.material_pallet_type import MaterialPalletTypeCreate, MaterialPalletTypeUpdate, MaterialPalletTypeDetail
from backend.auth.auth import get_current_user
from datetime import datetime
from typing import Optional
from backend.utils.consts import SERVER_INTERNAL_ERROR_MSG, PALLET_TYPE_NOT_FOUND_MSG
from backend.cypher_defs.cypher_material_pallet_type import (
    MATCH_PALLET_TYPE_BY_ID,
    GET_MATERIAL_PALLET_TYPE_LIST,
    CREATE_MATERIAL_PALLET_TYPE,
    UPDATE_MATERIAL_PALLET_TYPE,
    DELETE_MATERIAL_PALLET_TYPE_REL,
    DELETE_MATERIAL_PALLET_TYPE,
    GET_WORKBENCH_PALLET_TYPES,
    CHECK_PALLET_TYPE_EXISTS
)
from backend.utils.model_utils import fill_create_update_fields, fill_update_fields

router = APIRouter(prefix="/api/material-pallet-types", tags=["material-pallet-type"])

@router.get(
    "/",
    response_model=dict,
    summary="获取托盘类型列表",
    description="支持按托盘类型名称或ID模糊查询，返回所有托盘类型信息。"
)
async def get_material_pallet_type_list(keyword: Optional[str] = Query(None, description="托盘类型名称或ID")):
    try:
        cypher = GET_MATERIAL_PALLET_TYPE_LIST.format(where=f"WHERE p.materialPalletTypeName CONTAINS $keyword OR p.materialPalletTypeId CONTAINS $keyword")
        params = {"keyword": keyword}
        result = neo4j_driver.query(cypher, params)
        data = [r["p"] for r in result]
        data = filter_sensitive_fields(data)
        return {"code": 0, "msg": "success", "data": data}
    except Exception as e:
        logger.error(f"Error in get_material_pallet_type_list: {e}", exc_info=True)
        return {"code": 500, "msg": SERVER_INTERNAL_ERROR_MSG, "data": None}

@router.post(
    "/",
    response_model=dict,
    summary="创建托盘类型",
    description="创建新的托盘类型节点，ID不可重复。"
)
async def create_material_pallet_type(
    body: MaterialPalletTypeCreate,
    current_user: str = Depends(get_current_user)
):
    try:
        cypher = CHECK_PALLET_TYPE_EXISTS
        if neo4j_driver.query(cypher, {"materialPalletTypeId": body.materialPalletTypeId}):
            return {"code": 1011, "msg": "托盘类型ID已存在", "data": None}
        params = body.dict()
        params["createdBy"] = current_user
        params["createdAt"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        params["updatedBy"] = current_user
        params["updatedAt"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        cypher = CREATE_MATERIAL_PALLET_TYPE
        result = neo4j_driver.query(cypher, params)
        material_pallet_type = result[0]["p"] if result else None
        return {"code": 0, "msg": "success", "data": material_pallet_type}
    except Exception as e:
        logger.error(f"Error in create_material_pallet_type: {e}", exc_info=True)
        return {"code": 500, "msg": SERVER_INTERNAL_ERROR_MSG, "data": None}

@router.put(
    "/{materialPalletTypeId}",
    response_model=dict,
    summary="更新托盘类型信息",
    description="根据ID更新托盘类型基本信息。"
)
async def update_material_pallet_type(
    materialPalletTypeId: str = Path(...),
    body: MaterialPalletTypeUpdate = Body(...),
    current_user: str = Depends(get_current_user)
):
    try:
        cypher = MATCH_PALLET_TYPE_BY_ID
        if not neo4j_driver.query(cypher, {"materialPalletTypeId": materialPalletTypeId}):
            return {"code": 1013, "msg": PALLET_TYPE_NOT_FOUND_MSG, "data": None}
        set_clauses = []
        params = {"materialPalletTypeId": materialPalletTypeId}
        for k, v in body.dict(exclude_unset=True).items():
            if k == "materialPalletTypeId":
                continue  # 禁止修改ID
            set_clauses.append(f"p.{k} = ${{k}}")
            params[k] = v
        params = fill_update_fields(params, current_user)
        set_clauses.append("p.updatedBy = $updatedBy")
        set_clauses.append("p.updatedAt = $updatedAt")
        if set_clauses:
            cypher = UPDATE_MATERIAL_PALLET_TYPE.replace('{set_clauses}', ', '.join(set_clauses))
            result = neo4j_driver.query(cypher, params)
            material_pallet_type = result[0]["p"] if result else None
        else:
            material_pallet_type = None
        return {"code": 0, "msg": "success", "data": material_pallet_type}
    except Exception as e:
        logger.error(f"Error in update_material_pallet_type: {e}", exc_info=True)
        return {"code": 500, "msg": SERVER_INTERNAL_ERROR_MSG, "data": None}

@router.delete(
    "/{materialPalletTypeId}",
    response_model=dict,
    summary="删除托盘类型",
    description="根据ID删除托盘类型节点及其所有关联关系。"
)
async def delete_material_pallet_type(materialPalletTypeId: str = Path(...)):
    try:
        cypher = MATCH_PALLET_TYPE_BY_ID
        if not neo4j_driver.query(cypher, {"materialPalletTypeId": materialPalletTypeId}):
            return {"code": 1013, "msg": PALLET_TYPE_NOT_FOUND_MSG, "data": None}
        # 先删除与工台的关系
        cypher = DELETE_MATERIAL_PALLET_TYPE_REL
        neo4j_driver.query(cypher, {"materialPalletTypeId": materialPalletTypeId})
        # 再删除节点
        cypher = DELETE_MATERIAL_PALLET_TYPE
        neo4j_driver.query(cypher, {"materialPalletTypeId": materialPalletTypeId})
        return {"code": 0, "msg": "success", "data": None}
    except Exception as e:
        logger.error(f"Error in delete_material_pallet_type: {e}", exc_info=True)
        return {"code": 500, "msg": SERVER_INTERNAL_ERROR_MSG, "data": None}

@router.get("/workbenches/{benchId}/pallet-types", response_model=dict)
async def get_workbench_pallet_types(benchId: str = Path(...)):
    try:
        cypher = GET_WORKBENCH_PALLET_TYPES
        result = neo4j_driver.query(cypher, {"benchId": benchId})
        data = [r["p"] for r in result]
        return {"code": 0, "msg": "success", "data": data}
    except Exception as e:
        logger.error(f"Error in get_workbench_pallet_types: {e}", exc_info=True)
        return {"code": 500, "msg": SERVER_INTERNAL_ERROR_MSG, "data": None}

@router.get(
    "/{materialPalletTypeId}",
    response_model=dict,
    summary="获取托盘类型详情",
    description="根据ID获取托盘类型的详细信息。"
)
async def get_material_pallet_type_detail(materialPalletTypeId: str = Path(...)):
    try:
        cypher = MATCH_PALLET_TYPE_BY_ID
        result = neo4j_driver.query(cypher, {"materialPalletTypeId": materialPalletTypeId})
        data = result[0]["p"] if result else None
        return {"code": 0, "msg": "success", "data": data}
    except Exception as e:
        logger.error(f"Error in get_material_pallet_type_detail: {e}", exc_info=True)
        return {"code": 500, "msg": SERVER_INTERNAL_ERROR_MSG, "data": None} 